using AutoMapper;
using B.S.BaseData.Infrastructure;
using B.S.ProcessEgine.API.Applocations.Commands.FormNodes;
using B.S.ProcessEgine.Domain.Entities;
using B.S.ProcessEgine.ErrorCode;
using B.S.ProcessEgine.Infractructure.Interfaces;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.ProcessEgine.API.Applocations.CommandHandlers.FormNodes
{
    public class SaveFormNodesCommandHandler : IRequestHandler<SaveFormNodesCommand, ApiResult>
    {
        private readonly BaseDbContext _context;
        private readonly IFormNodeRepository _formNodeRepository;
        private readonly ILogger<SaveFormNodesCommandHandler> _logger;
        private readonly IMapper mapper;

        public SaveFormNodesCommandHandler(BaseDbContext context,
                                           IFormNodeRepository formNodeRepository,
                                           ILogger<SaveFormNodesCommandHandler> logger, IMapper mapper)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
            _formNodeRepository = formNodeRepository ?? throw new ArgumentNullException(nameof(formNodeRepository));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            this.mapper = mapper;
        }

        public async Task<ApiResult> Handle(SaveFormNodesCommand request, CancellationToken cancellationToken)
        {
            // 1. 校验
            if (request.Nodes == null || !request.Nodes.Any())
                return ApiResult.Fail("节点列表不能为空", StateCodeEnum.Fail);

            if (request.Nodes.Any(n => string.IsNullOrWhiteSpace(n.NodeName)))
                return ApiResult.Fail("表单名称不能为空", StateCodeEnum.Fail);

            if (request.Nodes.GroupBy(n => n.NodeNo).Any(g => g.Count() > 1))
                return ApiResult.Fail("节点编号不能重复", StateCodeEnum.Fail);

            try
            {
                // 2. 查询所有未删除的原节点，逻辑删除
                var nodes = mapper.Map<IList<Domain.Entities.FormNodes>>(request.Nodes);
                foreach (var node in nodes)
                {
                    node.IsDel = true;
                }
                await _formNodeRepository.UpdateRangeAsync(nodes);

                // 3. 添加新节点
                foreach (var dto in nodes)
                {
                    dto.NodeId = 0;
                    dto.IsDel = false;
                    dto.FormId = request.FormId;
                }
                await _formNodeRepository.AddRangeAsync(nodes);

                return ApiResult.Success(StateCodeEnum.Ok);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存表单节点出错");
                return ApiResult.Fail("保存表单节点出错", StateCodeEnum.Exception);
            }
        }
    }
}